package nl.hr.minor.mobilelife.j1213.jlr.words;

import java.util.ArrayList;

import nl.hr.minor.mobilelife.j1213.jlr.R;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class LevelActivity extends Activity implements View.OnClickListener, OnGlobalLayoutListener {

	private static final String LOG_TAG = LevelActivity.class.getSimpleName();

	private LinearLayout letterTilesContainer, dropZonesContainer;
	private LetterTiles letterTiles;
	private ArrayList<DropZone> dropZones;
	private TextView formedWord, valid, points;
	private Button button, resetButton, generateButton;
	private ProgressDialog progressDialog;
	
	private View content;
	private String randomWord;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.words_level);

		findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(this);

		initVars();

		letterTiles = new LetterTiles();
		dropZones = new ArrayList<DropZone>();

		for(int i = 0; i < 8; i++) {
			letterTiles.add(new LetterTile(this));
			dropZones.add(new DropZone(this));
		}
	}

	private void initVars() {
		button = (Button) findViewById(R.id.check);
		resetButton = (Button) findViewById(R.id.reset);
		resetButton.setOnClickListener(this);
		generateButton = (Button) findViewById(R.id.generate);
		generateButton.setOnClickListener(this);
		formedWord = (TextView) findViewById(R.id.formedword);
		valid = (TextView) findViewById(R.id.validword);
		
		points = (TextView) findViewById(R.id.point);
		button.setOnClickListener(this);
		content = findViewById(android.R.id.content);
		randomWord = new String();

		letterTilesContainer = (LinearLayout) findViewById(R.id.words_level_activity_letterstock);
		dropZonesContainer = (LinearLayout) findViewById(R.id.words_level_activity_dropzones);

		progressDialog = new ProgressDialog(this);
		progressDialog.setTitle("Woord controleren");
		progressDialog.setMessage("Zoeken...");
	}

	private void doNewWord(String newWord, int totalPanelWidth){

		letterTilesContainer.removeAllViews();
		dropZonesContainer.removeAllViews();

		int
		newWordLength = newWord.length(),
		tileWidthHeight = (int) (totalPanelWidth * 0.8) / newWordLength; // all tiles (w/o margin) consume 80% of totalPanelWidth

		for(int i = 0; i < 8; i++) {

			LetterTile lt = letterTiles.get(i);
			DropZone dz = dropZones.get(i);
			lt.dropZoneIndex = LetterTile.DROPZONE_INDEX_NO_POSITION;

			if(i < newWordLength) {
				lt.setVisibility(View.VISIBLE);
				lt.setGravity(Gravity.CENTER);
				lt.setTextSize((float) (tileWidthHeight * 0.3));
				lt.setText(Character.toString(newWord.charAt(i)));
				lt.setTag(Character.toString(newWord.charAt(i)));

				dz.setVisibility(View.VISIBLE);

				LinearLayout.LayoutParams lp = 
						new LinearLayout.LayoutParams(tileWidthHeight, tileWidthHeight, 100 / newWordLength);
				lp.setMargins(2, 2, 2, 2);

				letterTilesContainer.addView(lt, lp);
				dropZonesContainer.addView(dz, lp);

			} else { 
				lt.setVisibility(View.GONE);
				dz.setVisibility(View.GONE);
			}
		}
	}

	@Override
	public void onGlobalLayout() {
		Log.i(LOG_TAG, "onGLobalLayout called. Removing listener... Width: " + content.getWidth());
		content.getViewTreeObserver().removeGlobalOnLayoutListener(this);
		generateWord();
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	public void onClick(View view) {

		switch(view.getId()){
		case R.id.check:
			checkWord();
			break;
		case R.id.generate:
			generateWord();
			break;
		case R.id.reset:
			resetWord();
			break;
		}
	}

	public void checkWord(){

		ViewGroup viewGroup = (ViewGroup) findViewById(R.id.words_level_activity_dropzones);
		int size = viewGroup.getChildCount();

		StringBuilder sb = new StringBuilder();

		for(int i = 0; i < size; i++){
			View view = viewGroup.getChildAt(i);
			if(view instanceof TextView){
				sb.append(((TextView)view).getText().toString());
			}else{
				sb.append(" ");
			}
		}

		String checkWord = sb.toString().trim();
		if(checkWord.contains(" ")){
			Toast.makeText(this, "Woord mag een spaties bevatten.", Toast.LENGTH_LONG).show();
		}else{
			new CheckWord().execute(sb.toString().trim(), null, null);
		}
	}
	
	private void generateWord(){
		randomWord = WordTool.getInstance().getRandomWord(getAssets());
		randomWord = WordTool.getInstance().shuffle(randomWord);
		doNewWord(randomWord, content.getWidth());
		System.out.println("Generated word: "+randomWord);
	}
	

	private void resetWord() {
		doNewWord(randomWord, content.getWidth());
	}
	
	
	private void validWord(String userFormedWord) {
		System.out.println("In validWord");
		formedWord.setText(userFormedWord);
		valid.setText("Ja");
		points.setText(Integer.toString(Score.calculateScore(userFormedWord)));
		generateWord();
	}	

	private void invalidWord(String userFormedWord){
		System.out.println("In invalidWord");
		formedWord.setText(userFormedWord);
		valid.setText("Nee");
		points.setText("0");
	}


	private class CheckWord extends AsyncTask<String, Void, Boolean>{

		private String userFormedWord;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog.show();
		}

		@Override
		protected Boolean doInBackground(String... params) {
			userFormedWord = params[0];
			WordTool wordChecker = WordTool.getInstance();
			return wordChecker.check(userFormedWord, getAssets());
		}

		protected void onPostExecute(Boolean isValid){
			progressDialog.hide();
			if(isValid){
				validWord(userFormedWord);
			}else{
				invalidWord(userFormedWord);
			}
		}
	}
}
